/*
 * main.c
 *
 *  Created on: Aug 27, 2012
 *      Author: Adrian Ortega Garcia
 */

#include <stdlib.h>
#include "arg_parser.h"
#include "logging.h"
#include "elf_t.h"
#include "ehdr.h"
#include "shdr.h"
#include "phdr.h"
#include "common.h"
#include "xml_parser.h"

int dsmblr_log_level = LOG_LEVEL_INFO;

int main(int argc, char *argv[])
{
	int rc = 0;

	rc = parse_arguments(argc, argv);

	if(rc != 0){
		LOG_ERR("Error parsing arguments:  %d\n",rc);
		return rc;
	}

	// Set user defined log level
	dsmblr_log_level = arguments.log_level;

	// User just wants to display features
	if(arguments.display_features){
			print_available_features();
			return 0;
	}

	// Parse the XML file containing the opcodes definition
	parse_document("x86reference.xml");

	// Loop through all the files passed through the command line
	file_t * current = arguments.files;
	while( current != NULL ){
		Elf	elf;
		elf.shdr = 0;
		elf.phdr = 0;
		elf.name = current->file_name;
		elf.fd = open_file(elf.name);
		if(elf.fd == NULL){
			LOG_ERR("Error opening file: %s\n", current->file_name);
			current = current->next;
			continue;
		}

		LOG_INFO("File: %s\n", elf.name);

		 // Most of the options involve the ELF headers, so let's get them.
		read_elf_header(elf.fd, &elf.ehdr);
		elf.shdr = allocate_section_header_table(&elf.ehdr);
		elf.phdr = allocate_program_header_table(&elf.ehdr);
		// Read the tables if they were allocated
		if(elf.shdr) read_section_header_table(elf.fd, &elf.ehdr, elf.shdr);
		if(elf.phdr) read_program_header_table(elf.fd, &elf.ehdr, elf.phdr);

		// Now that we have the file opened, which feature does the user want to use?
		switch(arguments.feature)
		{
			case FEATURE_1:
				print_binary_content(elf.fd);
				break;
			case FEATURE_2:
				pretty_print_ehdr(&elf.ehdr);
				pretty_print_shdr(elf.fd, &elf.ehdr, elf.shdr);
				pretty_print_phdr(&elf.ehdr, elf.phdr);
				break;
			case PRINT_ELF_HDR:
				pretty_print_ehdr(&elf.ehdr);
				break;
			case PRINT_SECTION_HDR:
				pretty_print_shdr(elf.fd, &elf.ehdr, elf.shdr);

				break;
			case PRINT_PROGRAM_HDR:
				pretty_print_phdr(&elf.ehdr, elf.phdr);
				break;
			default:
				LOG_WARN("Unknown feature.\n");
				goto cleanup;
				break;
		}

		// We are all done, close the file and go to the next file
		fclose(elf.fd);
		if(elf.shdr) free(elf.shdr);
		if(elf.phdr) free(elf.phdr);
		current = current->next;
	}
cleanup:
	// Do not forget to free memory
	list_free_files(arguments.files);
	cleanup_section_names();
	return 0;
}



